package com.hjh.tool.util

import android.annotation.SuppressLint
import android.content.Context
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.elvishew.xlog.XLog
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.common.InputImage
import java.lang.ref.WeakReference

object MlKitQrScanUtil {

    private var cameraProvider: WeakReference<ProcessCameraProvider>? = null
    private var fakeLifecycleOwner: FakeLifecycleOwner? = null

    fun startScan(context: Context, onQrCodeScanned: (String) -> Unit) {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
        cameraProviderFuture.addListener({
            val provider = cameraProviderFuture.get()
            cameraProvider = WeakReference(provider)
            bindPreviewAndAnalyzer(provider, context, onQrCodeScanned)
        }, ContextCompat.getMainExecutor(context))
    }

    private fun bindPreviewAndAnalyzer(
        provider: ProcessCameraProvider,
        context: Context,
        onQrCodeScanned: (String) -> Unit
    ) {
        val preview = Preview.Builder().build()
        val analyzer = ImageAnalysis.Builder()
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()

        analyzer.setAnalyzer(
            ContextCompat.getMainExecutor(context),
            BarcodeAnalyzer(onQrCodeScanned)
        )

        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

        provider.unbindAll()

        // 使用虚拟生命周期
        fakeLifecycleOwner = FakeLifecycleOwner()
        provider.bindToLifecycle(fakeLifecycleOwner!!, cameraSelector, preview, analyzer)
    }

    /**
     * 手动释放扫码相关资源（解绑相机、释放生命周期等）
     */
    fun stopScan() {
        cameraProvider?.get()?.unbindAll()
        cameraProvider?.clear()
        cameraProvider = null
        fakeLifecycleOwner = null
        XLog.tag("MlKitQrScanUtil").i("扫码资源已释放")
    }

    private class FakeLifecycleOwner : LifecycleOwner {

        private val registry: LifecycleRegistry = LifecycleRegistry(this).apply {
            currentState = Lifecycle.State.CREATED
            currentState = Lifecycle.State.STARTED
            currentState = Lifecycle.State.RESUMED
        }

        override val lifecycle: Lifecycle = registry
    }

    private class BarcodeAnalyzer(
        private val onQrCodeScanned: (String) -> Unit
    ) : ImageAnalysis.Analyzer {

        private val scanner = BarcodeScanning.getClient(
            BarcodeScannerOptions.Builder()
                .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
                .build()
        )

        @SuppressLint("UnsafeOptInUsageError")
        override fun analyze(imageProxy: ImageProxy) {
            val mediaImage = imageProxy.image ?: run {
                imageProxy.close()
                return
            }

            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

            scanner.process(image)
                .addOnSuccessListener { barcodes ->
                    for (barcode in barcodes) {
                        barcode.rawValue?.let {
                            onQrCodeScanned(it)
                            // 如需自动停止扫码，可在此调用 stopScan()
                        }
                    }
                }
                .addOnFailureListener { XLog.tag("QrScanService").e("扫码失败", it) }
                .addOnCompleteListener { imageProxy.close() }
        }
    }
}
